package com.yz.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;

public class ServerReaderThread extends Thread{
    private Socket socket;
    public ServerReaderThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            //规定一个消息类型1代表登录2代表群聊3代表私聊
            //先从socket管道中读取消息类型编号
            DataInputStream dis = new DataInputStream(socket.getInputStream());//获取输入流
            while (true) {
                int msgType = dis.readInt();//读取消息类型编号
                switch (msgType){
                    case 1:
                        //System.out.println("用户登录");
                        String nickname = dis.readUTF();//读取用户昵称
                        Server.onlineSockets.put(socket, nickname);//将登录的昵称和socket对象存到集合中
                        updateClientOnLineUserList();
                        break;
                    case 2:
                        //System.out.println("群聊");
                        String msg = dis.readUTF();
                        sendMsgToAll(msg);
                        break;
                    case 3:
                        //System.out.println("私聊");
                        String msg1 = dis.readUTF();
                        sendMsgToOne(msg1);
                        break;
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            System.out.println("客户端断开了");
            Server.onlineSockets.remove(socket);
            updateClientOnLineUserList();
        }
    }

    private void sendMsgToOne(String msg) {
        // 提取私聊的目标用户名（格式为 "@username message"）
        String[] parts = msg.split(" ", 2); // 分割消息，确保我们可以分离出目标用户和消息
        String targetUsername = parts[0].substring(1); // 获取目标用户名，去掉前面的@
        String messageContent = parts[1]; // 剩余的是消息内容

        Socket targetSocket = null;

        // 查找目标用户对应的socket
        for (Socket clientSocket : Server.onlineSockets.keySet()) {
            if (Server.onlineSockets.get(clientSocket).equals(targetUsername)) {
                targetSocket = clientSocket;
                break;
            }
        }

        if (targetSocket != null) {
            try {
                DataOutputStream dos = new DataOutputStream(targetSocket.getOutputStream());
                dos.writeInt(3); // 3代表私聊
                dos.writeUTF(Server.onlineSockets.get(socket)); // 发送发送方的用户名
                dos.writeUTF(messageContent); // 发送消息内容
                dos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    private void sendMsgToAll(String msg) {
        //先把这个消息拼装好，再发给所有在线的socket管道
        StringBuffer sb = new StringBuffer();
        String name = Server.onlineSockets.get(socket);//拿到当前发送消息的用户的昵称
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EEE a");
        String time = now.format(dtf);
        String msgResult = sb.append(name).append(" ").append(time).append(":").append("\r\n")
                .append(msg).append("\r\n").toString();//拼装好的消息
        for (Socket socket : Server.onlineSockets.keySet()) {
            try {
                DataOutputStream dos = new DataOutputStream(socket.getOutputStream());//获取输出流
                dos.writeInt(2);//发送消息类型编号
                dos.writeUTF(msgResult);//发送消息内容
                dos.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void updateClientOnLineUserList() {
        //更新所有客户端的在线用户列表
        //拿到所有的在线客户端的name，把这些名字转发给全部在线的socket管道
        Collection<String> onLineUsers  = Server.onlineSockets.values();//拿到所有的在线用户的昵称
        for (Socket socket : Server.onlineSockets.keySet()) {
            try {
                DataOutputStream dos = new DataOutputStream(socket.getOutputStream());//获取输出流
                dos.writeInt(1);//发送消息类型编号
                dos.writeInt(onLineUsers.size());//发送在线人数
                for (String onLineUser : onLineUsers) {
                    dos.writeUTF(onLineUser);//再发送在线用户列表
                }
                dos.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
